package com.kingint.web.admin.serve.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kingint.mbg.bas.entity.BasFloor;
import com.kingint.mbg.bas.entity.BasRepairGoods;
import com.kingint.mbg.bas.entity.BasRoom;
import com.kingint.mbg.bas.entity.BasWarrantyItems;
import com.kingint.mbg.bas.mapper.BasFloorMapper;
import com.kingint.mbg.bas.mapper.BasRoomMapper;
import com.kingint.mbg.bas.mapper.BasWarrantyItemsMapper;
import com.kingint.mbg.dto.MemberReturn;
import com.kingint.mbg.dto.department.DepartmentQueryParam;
import com.kingint.mbg.dto.department.DepartmentRepairBack;
import com.kingint.mbg.dto.department.DepartmentRepairParam;
import com.kingint.mbg.ser.entity.*;
import com.kingint.mbg.ser.mapper.SerCheckWorkMiddleMapper;
import com.kingint.mbg.ser.mapper.SerDepartmentRepairMapper;
import com.kingint.mbg.ser.mapper.SerDepartmentRepairMiddleMapper;
import com.kingint.mbg.ser.mapper.SerWorkOrderMapper;
import com.kingint.mbg.sys.entity.UmsMember;
import com.kingint.mbg.sys.mapper.UmsMemberMapper;
import com.kingint.web.admin.serve.service.SerDepartmentRepairService;
import com.kingint.web.admin.serve.service.SerReceiveWorkMiddleService;
import com.kingint.web.portal.serve.service.ActivitiCancelService;
import com.kingint.web.sys.service.UmsAdminService;
import com.kingint.web.util.CharUtil;
import com.kingint.web.util.WorkType;
import com.kingint.web.util.WorkTypeUtil;
import com.kingint.web.vo.RepairBean;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.*;

/**
 * <p>
 * 部门保修表 服务实现类
 * </p>
 *
 * @author wxh
 * @since 2020-12-20
 */
@Service
@Slf4j
public class SerDepartmentRepairServiceImpl extends ServiceImpl<SerDepartmentRepairMapper, SerDepartmentRepair> implements SerDepartmentRepairService {

    @Resource
    private UmsAdminService adminService;
    @Resource
    private SerDepartmentRepairMapper departmentRepairMapper;
    @Resource
    private SerWorkOrderMapper workOrderMapper;
    @Resource
    private SerDepartmentRepairMiddleMapper departmentRepairMiddleMapper;
    @Resource
    private RepairBean repairBean;
    @Resource
    private ActivitiCancelService activitiCancelService;
    @Resource
    private TaskService taskService;
    @Resource
    private UmsMemberMapper memberMapper;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private BasRoomMapper roomMapper;
    @Resource
    private BasFloorMapper floorMapper;
    @Resource
    private BasWarrantyItemsMapper warrantyItemsMapper;
    @Resource
    private SerReceiveWorkMiddleService receiveWorkMiddleService;
    @Resource
    private SerCheckWorkMiddleMapper checkWorkMiddleMapper;

    @Override
    public IPage<SerDepartmentRepair> getAllDepartmentRepairList(DepartmentQueryParam queryParam, Integer pageNum, Integer pageSize) {
        //查询对应酒店下的部门维修单
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("该账号未关联酒店id");
            return null;
        }
        //获取部门维修工单id
        Integer workTypeId = WorkTypeUtil.getWorkTypeIdByName(WorkType.repairName);
        queryParam.setHotelId(hotelId);
        queryParam.setWorkTypeId(workTypeId);
        //查询对应的维修单信息 全部查询默认0， 1,未指派，2,处理中，3，待验收，4.挂起，5，完成
        //部门问题把小度的区分出来
        IPage<SerDepartmentRepair> page = new Page<>(pageNum, pageSize);
        IPage<SerDepartmentRepair> list = departmentRepairMapper.getAllDepartmentList(page, queryParam);
        //处理相关的信息（房间，保修人）
        if(!StringUtils.isEmpty(list.getRecords())){
            List<SerDepartmentRepair> records = list.getRecords();
            records.stream().forEach(s->{
                SerWorkOrder workOrder = s.getWorkOrder();
                Integer roomId = workOrder.getRoomId();
                BasRoom basRoom = roomMapper.selectById(roomId);
                workOrder.setRoomNum(basRoom.getRoomNum());
                Long submitUserId = workOrder.getSubmitUserId();
                UmsMember umsMember = memberMapper.selectById(submitUserId);
                if(umsMember!=null)
                workOrder.setSubmitUserName(umsMember.getUsername());
            });
        }
        return list;
    }

    @Override
    public int addDepartmentRepair(DepartmentRepairParam departmentRepairParam) {
        UmsMember currentMember = adminService.getCurrentMember();
        SerWorkOrder workOrder = new SerWorkOrder();
        BeanUtils.copyProperties(departmentRepairParam, workOrder);
        workOrder.setSubmitUserId(currentMember.getId());//提交人员
        workOrder.setWorkTypeId(WorkTypeUtil.getWorkTypeIdByName(WorkType.repairName));//对应的工单类型怎么查询出来
        workOrder.setCreateTime(new Date());
        workOrder.setHotelId(currentMember.getHotelId());//对应酒店id
        workOrder.setWorkOrderStatus(0);//订单类型普通
        workOrder.setOrderSn(CharUtil.generateOrderSn());//工单号
        int insert = workOrderMapper.insert(workOrder);//插入相关的保修信息

        SerDepartmentRepair repair = new SerDepartmentRepair();
        BeanUtils.copyProperties(departmentRepairParam, repair);//拷贝信息
        repair.setWorkId(workOrder.getId());
        //保修物品信息
        List<BasWarrantyItems> warrantyItemsList = departmentRepairParam.getWarrantyItemsList();
        List<BasWarrantyItems> newList=new ArrayList<>();
        if(!CollectionUtils.isEmpty(warrantyItemsList)){
            for (BasWarrantyItems info:warrantyItemsList) {
                BasWarrantyItems basWarrantyItems = warrantyItemsMapper.selectById(info.getId());
                newList.add(basWarrantyItems);
            }
        }
        Object o = JSONObject.toJSON(newList);//转换为json
        repair.setWarrantyContent(o.toString());
        repair.setCreateTime(new Date());
        departmentRepairMapper.insert(repair);

        //处理维修人员
        List<MemberReturn> memberList = departmentRepairParam.getMemberList();
        MemberReturn memberReturn = memberList.get(0);
        SerDepartmentRepairMiddle middle = new SerDepartmentRepairMiddle();
        middle.setDepartmentRepairId(repair.getId());
        middle.setRepairUserId(memberReturn.getId());
        middle.setCreateTime(new Date());
        departmentRepairMiddleMapper.insert(middle);

        //添加相关接单
        SerReceiveWorkMiddle workMiddle = new SerReceiveWorkMiddle();
        workMiddle.setWorkId(workOrder.getId());
        workMiddle.setReceiveUserId(memberReturn.getId());
        receiveWorkMiddleService.insertReceiveWorkInfo(workMiddle);

        //添加总单与检查人员之间的中间表
        SerCheckWorkMiddle middle1 = new SerCheckWorkMiddle();
        middle1.setWorkId(workOrder.getId());
        middle1.setCreateTime(new Date());
        middle1.setCheckUserId(departmentRepairParam.getCheckUserId());
        checkWorkMiddleMapper.insert(middle1);

        //同时启动对应的流程实例
        HashMap<String, Object> variables = new HashMap<>();
        variables.put(repairBean.getCreateNameEl(), currentMember.getUsername());//下一步流程执行人
        //流程实例id
        String businessKey = repairBean.getProcessInstanceKey() + "_" + currentMember.getHotelId() + "_" + workOrder.getId();//业务相关参数

        String processInstanceId = activitiCancelService.startProcess(repairBean.getProcessInstanceKey(), businessKey, variables);


        //完成接单节点
        Map<String, Object> map = new HashMap<>();
        map.put(repairBean.getReceiveStatus(), 1);
        UmsMember umsMember = memberMapper.selectById(memberReturn.getId());
        map.put(repairBean.getReceiveNameEl(), umsMember.getUsername());//下一阶段处理人

        Task task1 = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();

        taskService.complete(task1.getId(), map);

        //更新流程实例id
        workOrder.setProcessInstanceId(processInstanceId);
        workOrderMapper.updateById(workOrder);
        return insert;
    }

    @Override
    public DepartmentRepairBack getDepartmentRepairInfo(Integer id) {
        SerDepartmentRepair repair = departmentRepairMapper.selectById(id);
        DepartmentRepairBack back = new DepartmentRepairBack();
        BeanUtils.copyProperties(repair,back);//拷贝相关信息

        Integer workId = repair.getWorkId();
        SerWorkOrder workOrder = workOrderMapper.selectById(workId);
        back.setHotelId(workOrder.getHotelId());
        back.setSubmitUserId(workOrder.getSubmitUserId());
        UmsMember umsMember = memberMapper.selectById(workOrder.getSubmitUserId());
        back.setSubmitUserName(umsMember.getUsername());
        back.setRoomId(workOrder.getRoomId());
        back.setOrderSn(workOrder.getOrderSn());

        UmsMember member = memberMapper.selectById(repair.getCheckUserId());
        back.setCheckUserName(member.getUsername());

        //查询对应的相关信息
        BasRoom basRoom = roomMapper.selectById(workOrder.getRoomId());
        back.setRoomNum(basRoom.getRoomNum());
        back.setFloorId(basRoom.getFloorId());
        BasFloor basFloor = floorMapper.selectById(basRoom.getFloorId());
        back.setFloorName(basFloor.getFloorName());


        //处理相关的json
        String warrantyContent = back.getWarrantyContent();//保修物品
        if (!StringUtils.isEmpty(warrantyContent)) {
            List<BasWarrantyItems> items = JSONObject.parseArray(warrantyContent, BasWarrantyItems.class);
            back.setWarrantyItems(items);
        }
        String repairGoods = back.getRepairGoods();
        if (!StringUtils.isEmpty(repairGoods)) {//维修耗材
            List<BasRepairGoods> goods = JSONObject.parseArray(repairGoods, BasRepairGoods.class);
            back.setRepairGoodsList(goods);
        }
        //查询中间表
        QueryWrapper<SerDepartmentRepairMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("department_repair_id", id)
                .eq("status", 0);
        List<SerDepartmentRepairMiddle> middles = departmentRepairMiddleMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(middles)) {
            List<MemberReturn> memberList = new ArrayList<>();
            middles.stream().forEach(s -> {
                MemberReturn memberInfoById = memberMapper.getMemberInfoById(s.getRepairUserId());
                memberList.add(memberInfoById);
            });
            back.setMemberList(memberList);
        }
        return back;
    }

    @Override
    public Integer deleteRepairInfo(Integer id) {
        SerDepartmentRepair repair = departmentRepairMapper.selectById(id);
        //修改总单状态
        Integer workId = repair.getWorkId();
        SerWorkOrder order = new SerWorkOrder();
        order.setId(workId);
        order.setStatus(1);
        int i = workOrderMapper.updateById(order);

        //更改中间表信息
        QueryWrapper<SerDepartmentRepairMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("department_repair_id", id);
        SerDepartmentRepairMiddle middle = new SerDepartmentRepairMiddle();
        middle.setStatus(1);
        departmentRepairMiddleMapper.update(middle, wrapper);
        //再查询是否有流程实例，删除流程实例
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        String processInstanceId = serWorkOrder.getProcessInstanceId();

        runtimeService.deleteProcessInstance(processInstanceId, "总工单已经删除");
        return i;
    }

    @Override
    public Integer hangUpInfo(Integer workId) {
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        String processInstanceId = serWorkOrder.getProcessInstanceId();
        //查询
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        HashMap<String, Object> map = new HashMap<>();
//        map.put("rejectStatus", 1);//拒绝，驳回
        map.put("completeStatus", 0);//拒绝驳回
        taskService.complete(task.getId(), map);
        return 1;
    }

    @Override
    public Integer checkWorkOrder(Integer workId,Integer status) {
        ///TODO 这里还需要判断当前用户的身份才能进行操作
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        String processInstanceId = serWorkOrder.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        //完成验收checkStatus
        if(!StringUtils.isEmpty(task)){
            Map<String,Object> map=new HashMap<>();
            map.put(repairBean.getRejectStatus(),status);//这里所有的都可以使用
            taskService.setVariables(task.getId(),map);
            taskService.complete(task.getId());
            return 1;
        }
        return 0;
    }

    @Override
    public int changeHandleUser(Integer id, Long memberId) {
        SerDepartmentRepair repair = departmentRepairMapper.selectById(id);
        UmsMember member = memberMapper.selectById(memberId);
        //添加中间表 ser_receive_work_middle 维修人员接受
        SerReceiveWorkMiddle middle = new SerReceiveWorkMiddle();
        middle.setWorkId(repair.getWorkId());
        middle.setReceiveUserId(memberId);
        receiveWorkMiddleService.insertReceiveWorkInfo(middle);

        SerWorkOrder serWorkOrder = workOrderMapper.selectById(repair.getWorkId());

        //查询对应的businessKey的流程实例
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();
        if (!StringUtils.isEmpty(task)) {
            HashMap<String, Object> map = new HashMap<>();
            map.put(repairBean.getReceiveStatus(), 1);//确定状态
            map.put(repairBean.getReceiveNameEl(), member.getUsername());//下一阶段处理人
            taskService.setVariables(task.getId(), map);
            taskService.complete(task.getId());
            return 1;
        }
        log.debug("没有查询到相关的任务流程");
        return 0;
    }
}
